package com.ld.common.util.filelistener.jnotify;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.ld.common.util.filelistener.jnotify.impl.AbstractChangedHandler;
import com.ld.shieldsb.common.core.model.Result;
import com.ld.shieldsb.common.core.util.PathUtil;
import com.ld.shieldsb.common.core.util.StringUtils;

import lombok.extern.slf4j.Slf4j;
import net.contentobjects.jnotify.JNotify;
import net.contentobjects.jnotify.JNotifyException;

@Slf4j
/**
 * 文件变化监听器（jnotify版），tomcat下开发时可能存在二级制文件删除的问题，需自行完善
 * 
 * @ClassName FileChangedListener
 * @author <a href="mailto:donggongai@126.com" target="_blank">吕凯</a>
 * @date 2019年1月17日 下午5:04:56
 *
 */
public class FileChangedListenerManager {
    private static final List<Integer> watchIds = new ArrayList<>();
    private static final Map<String, FileChangedListenerModel> LISTENER_MAP = new LinkedHashMap<>(); // 管理器

    public static void main(String[] args) {
        try {
            FileChangedListenerModel listener = new FileChangedListenerModel();
            listener.setName("test");
            listener.setKeyCode("test");
            listener.setPath(PathUtil.getClassRootPath() + "com/ld");
            listener.setListener(new AbstractChangedHandler());
            FileChangedListenerManager.register(listener);
            FileChangedListenerManager.start(listener.getKeyCode());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Result register(FileChangedListenerModel listener) {
        Result result = new Result();
        result.setSuccess(false);
        String keyCode = listener.getKeyCode();
        if (StringUtils.isBlank(listener.getName())) {
            result.setMessage("name不能为空！");
            return result;
        }
        if (StringUtils.isBlank(keyCode)) {
            result.setMessage("识别码(KeyCode)不能为空！");
            return result;
        }
        FileChangedListenerModel cacheModel = LISTENER_MAP.get(keyCode);
        if (cacheModel != null) {
            result.setMessage("识别码(KeyCode)为" + keyCode + "的监听器已经存在！监听器名称为：" + cacheModel.getName());
            return result;
        }
        // 文件监控线程
        log.warn("注册监听器：" + listener.getName() + " " + listener.getPath());
        // 添加监听
        // int watchID = JNotify.addWatch(listener.getPath(), listener.getMask(), listener.isWatchSubtree(), listener.getListener());
        // listener.setWatchID(watchID);
        // watchIds.add(watchID);
        LISTENER_MAP.put(keyCode, listener);
        result.setSuccess(true);
        return result;
    }

    public static Result start(String keyCode) throws JNotifyException {
        Result result = new Result();
        result.setSuccess(false);
        if (!LISTENER_MAP.containsKey(keyCode)) {
            result.setMessage("识别码(KeyCode)为" + keyCode + "的监听器尚未注册，请先注册！");
            return result;
        }
        FileChangedListenerModel listener = LISTENER_MAP.get(keyCode);
        // 文件监控线程
        log.warn("启动文件监听 监听目录：" + listener.getPath());
        // 添加监听
        int watchID = JNotify.addWatch(listener.getPath(), listener.getMask(), listener.isWatchSubtree(), listener.getListener());
        listener.setWatchID(watchID);
        listener.setStarted(true);
        watchIds.add(watchID);
        result.setSuccess(true);
        return result;
    }

    /**
     * 停止监听器
     * 
     * @Title stop
     * @author 吕凯
     * @date 2019年1月18日 上午9:03:57
     * @param keyCode
     * @return Result
     */
    public static Result stop(String keyCode) {
        Result result = new Result();
        result.setSuccess(false);
        if (!LISTENER_MAP.containsKey(keyCode)) {
            result.setMessage("识别码(KeyCode)为" + keyCode + "的监听器尚未注册，请先注册！");
            return result;
        }
        FileChangedListenerModel listener = LISTENER_MAP.get(keyCode);
        Integer watchId = listener.getWatchID();
        if (watchId == null) {
            result.setMessage("识别码(KeyCode)为" + keyCode + "的监听器尚未启动！");
            return result;
        }
        try {
            JNotify.removeWatch(watchId);
        } catch (Exception e) {
            log.error("", e);
        }
        watchIds.remove(watchId);
        LISTENER_MAP.remove(keyCode);
        result.setSuccess(true);
        return result;
    }

    /**
     * 关闭监听
     * 
     * @throws IOException
     */
    public static void shutdown() {
        if (watchIds != null && watchIds.isEmpty()) {
            watchIds.forEach(watchId -> {
                try {
                    JNotify.removeWatch(watchId);
                } catch (Exception e) {
                    log.error("", e);
                }
            });
            watchIds.clear();
            LISTENER_MAP.clear();
        }
    }

    /**
     * 移除文件监听
     * 
     * @Title removeWatch
     * @author 吕凯
     * @date 2019年1月17日 下午5:12:47
     * @param watchId
     * @return
     * @throws IOException
     *             boolean
     */
    public static boolean removeWatch(Integer watchId) throws IOException {
        try {
            return JNotify.removeWatch(watchId);
        } catch (Exception e) {
            log.error("移除文件监听出错！", e);
        }
        return false;
    }

}
